package com.example.hibernate.demo.service;

import com.example.hibernate.demo.entity.BankTransferPayment;
import com.example.hibernate.demo.entity.CreditCardPayment;
import com.example.hibernate.demo.entity.Payment;
import com.example.hibernate.demo.repository.PaymentRepository;
import jakarta.persistence.EntityNotFoundException;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;

@Service
@RequiredArgsConstructor
public class PaymentService {
    
    private final PaymentRepository paymentRepository;
    
    @Transactional(readOnly = true)
    public List<Payment> findAll() {
        return paymentRepository.findAll();
    }
    
    @Transactional(readOnly = true)
    public Payment findById(Long id) {
        return paymentRepository.findById(id)
                .orElseThrow(() -> new EntityNotFoundException("Payment not found with id: " + id));
    }
    
    @Transactional(readOnly = true)
    public List<Payment> findByStatus(Payment.PaymentStatus status) {
        return paymentRepository.findByStatus(status);
    }
    
    @Transactional(readOnly = true)
    public List<Payment> findByDateRange(LocalDateTime start, LocalDateTime end) {
        return paymentRepository.findByPaymentDateBetween(start, end);
    }
    
    @Transactional(readOnly = true)
    public List<Payment> findByAmountGreaterThan(BigDecimal amount) {
        return paymentRepository.findByAmountGreaterThan(amount);
    }
    
    @Transactional(readOnly = true)
    public List<Payment> findAllCreditCardPayments() {
        return paymentRepository.findAllCreditCardPayments();
    }
    
    @Transactional(readOnly = true)
    public List<Payment> findAllBankTransferPayments() {
        return paymentRepository.findAllBankTransferPayments();
    }
    
    @Transactional
    public CreditCardPayment saveCreditCardPayment(CreditCardPayment payment) {
        return paymentRepository.save(payment);
    }
    
    @Transactional
    public BankTransferPayment saveBankTransferPayment(BankTransferPayment payment) {
        return paymentRepository.save(payment);
    }
    
    @Transactional
    public Payment updateStatus(Long id, Payment.PaymentStatus status) {
        Payment payment = findById(id);
        payment.setStatus(status);
        return paymentRepository.save(payment);
    }
    
    @Transactional
    public void delete(Long id) {
        Payment payment = findById(id);
        paymentRepository.delete(payment);
    }
}